#ifndef __QUANTITY_H__
#define __QUANTITY_H__

#include <iostream>
using namespace std;

template <class T>
class Quantity;

template <class T>
ostream& operator << (ostream& out, const Quantity <T>& quantity);

template <class T>
class Quantity {
public:
   Quantity operator + (const Quantity quantity) const;
   Quantity operator - (const Quantity quantity) const;
   Quantity operator % (const Quantity quantity) const;
   int  operator /  (const Quantity quantity) const;
   bool operator == (const Quantity quantity) const;
   friend ostream& operator << <>(ostream& out, const Quantity&);

   Quantity (int amount,  const T& unit);

private:
   Quantity (int quantity);
  
   int m_amount;
};

template <class T>
Quantity<T>::Quantity (int amount, const T& unit)
{
   m_amount = unit.toBaseUnit (amount);
}

template <class T>
Quantity<T>::Quantity (int amount)
{
   m_amount = amount;
}

template <class T>
bool Quantity<T>::operator == (const Quantity quantity) const
{
   return m_amount == quantity.m_amount;
}

template <class T>
Quantity<T> Quantity<T>::operator + (const Quantity<T> quantity) const
{
   return Quantity<T> (m_amount + quantity.m_amount);
}

template <class T>
Quantity<T> Quantity<T>::operator - (const Quantity<T> quantity) const
{
   return Quantity<T> (m_amount - quantity.m_amount);
}

template <class T>
int Quantity<T>::operator / (const Quantity<T> quantity) const
{
   return m_amount / quantity.m_amount;
}

template <class T>
Quantity<T> Quantity<T>::operator % (const Quantity<T> quantity) const
{
   return Quantity<T> (m_amount % quantity.m_amount);
}

template <class T>
ostream& operator << (ostream& out, const Quantity <T>& quantity)
{
    return T::output (out, quantity);
}

template <class T>
ostream& outputInUnit (ostream& out, const Quantity <T> quantity, const T& unit)
{
   int amount = quantity / Quantity <T> (1, unit);
   
   if (amount != 0)
      out << amount << " " << unit <<" ";

   return out;
}

#endif 

